package com.yilin.tms.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yilin.commons.util.ArrayUtil;
import com.yilin.commons.util.StringUtil;
import com.yilin.tms.core.commons.utils.QueryUtil;
import com.yilin.tms.core.entity.system.system.Menu;
import com.yilin.tms.core.entity.system.system.MenuOperate;
import com.yilin.tms.core.entity.user.UserType;
import com.yilin.tms.system.mapper.MenuMapper;
import com.yilin.tms.system.mapper.MenuOperateMapper;
import com.yilin.tms.system.service.IMenuService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
public class MenuService extends ServiceImpl<MenuMapper, Menu> implements IMenuService {

    @Resource
    MenuMapper menuMapper;
    @Resource
    MenuOperateMapper menuOperateMapper;

    @Override
    public List<Menu> getMenuList(Menu query) {
        if (query.getSort() == null) query.setSort("soft-ASC");
        QueryWrapper<Menu> queryWrapper = QueryUtil.andQueryWrapper(new QueryWrapper<>(), query);
        List<Menu> menuList = menuMapper.selectList(queryWrapper);
        if (ArrayUtil.containsBy(menuList, o -> "0".equals(o.getId()))) return menuList;
        return addParent(menuList);
    }

    @Override
    public List<Menu> getChildMenuList(Menu query, String parentId) {
        if (query.getSort() == null) query.setSort("soft-ASC");
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", parentId);
        queryWrapper = QueryUtil.andQueryWrapper(queryWrapper, query);
        List<Menu> menus = menuMapper.selectList(queryWrapper);
        for (Menu menu : menus) {
            Long count = menuMapper.selectCount(new QueryWrapper<Menu>().eq("parent_id", menu.getId()));
            menu.setChildrenCount(count);
            menu.setHasChildren(count > 0);
        }
        return menus;
    }

    @Override
    public List<Menu> getMenuListByCodes(String[] menuCodes) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("code", Arrays.asList(menuCodes));
        queryWrapper.orderByAsc("soft");
        List<Menu> menuList = menuMapper.selectList(queryWrapper);
        if (ArrayUtil.containsBy(menuList, o -> "0".equals(o.getId()))) return menuList;
        return addParent(menuList);
    }

    @Override
    public List<Menu> getMenuListByUserTypeAndCodes(UserType userType, String[] menuCodes) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("code", Arrays.asList(menuCodes));
        queryWrapper.like("target_user_types", userType.name());//货主，车主，平台
        queryWrapper.orderByAsc("soft");
        List<Menu> menuList = menuMapper.selectList(queryWrapper);
        if (ArrayUtil.containsBy(menuList, o -> "0".equals(o.getId()))) return menuList;
        return addParent(menuList);
    }

    // 无论怎么查询 必须返回上级树
    private List<Menu> addParent(List<Menu> menuList) {
        List<Menu> parentList = new ArrayList<>();
        for (Menu api : menuList) excParent(parentList, api);
        return ArrayUtil.mergeList(menuList, parentList, (obj1, obj2) -> obj1.getId().equals(obj2.getId()));
    }

    // ### 返回上级树
    private List<Menu> excParent(List<Menu> list, Menu menu) {
        if (menu.getParentId().equals("-1")) return list;
        Menu parent = menuMapper.selectById(menu.getParentId());
        if (!ArrayUtil.containsBy(list, o -> parent.getId().equals(o.getId()))) list.add(parent);
        return excParent(list, parent);
    }


    @Override
    public void saveMenu(Menu menu) {
        if (menu.getId() == null) {
            menu.setCreateTime(new Date());
            menuMapper.insert(menu);
        } else {
            menu.setUpdateTime(new Date());
            menuMapper.updateById(menu);
        }
        //查询上级结构目录，生成用户标签
        if (menu.getMenuType() != Menu.MenuType.layout) {
            excAttachMaskParent(menu);
        }
    }

    /// 自动贴标签
    private boolean excAttachMaskParent(Menu menu) {
        if (menu.getParentId().equals("-1")) return true;
        Menu parentMenu = menuMapper.selectById(menu.getParentId());
        if (parentMenu.getTargetUserTypes() == null) parentMenu.setTargetUserTypes("");
        List<String> splitParentTypes = new ArrayList<>();
        /// 刷新上级标签
        List<Menu> childMenuList = getMenuByParentId(parentMenu.getId());
        for (Menu childMenu : childMenuList) {
            if (childMenu.getTargetUserTypes() == null) childMenu.setTargetUserTypes("");
            List<String> stringList = Arrays.asList(childMenu.getTargetUserTypes().split(","));
            for (String splitType : new ArrayList<>(stringList)) if (!splitParentTypes.contains(splitType) && StringUtil.isNotEmpty(splitType)) splitParentTypes.add(splitType);
        }
        parentMenu.setTargetUserTypes(String.join(",", splitParentTypes));
        menuMapper.updateById(parentMenu);
        return excAttachMaskParent(parentMenu);
    }

    @Override
    public List<Menu> getMenuByParentId(String parentId) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", parentId);
        return menuMapper.selectList(queryWrapper);
    }

    @Override
    public void saveMenuOperate(MenuOperate operate) {
        if (operate.getId() == null) {
            operate.setCreateTime(new Date());
            menuOperateMapper.insert(operate);
        } else {
            operate.setUpdateTime(new Date());
            menuOperateMapper.updateById(operate);
        }
    }

    @Override
    public List<MenuOperate> getMenuOperateListByMenuId(String menuId) {
        QueryWrapper<MenuOperate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("menu_id", menuId);
        queryWrapper.orderByAsc("soft");
        return menuOperateMapper.selectList(queryWrapper);
    }

    @Override
    public List<MenuOperate> getMenuOperateListByMenuCode(String menuCode) {
        QueryWrapper<MenuOperate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("menu_code", menuCode);
        queryWrapper.orderByAsc("soft");
        return menuOperateMapper.selectList(queryWrapper);
    }

    @Override
    public List<MenuOperate> getMenuOperateListByCodes(String menuCode, String[] menuOperateCodes) {
        QueryWrapper<MenuOperate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("menu_code", menuCode);
        queryWrapper.in("code", Arrays.asList(menuOperateCodes));
        queryWrapper.orderByAsc("soft");
        return menuOperateMapper.selectList(queryWrapper);
    }

    @Override
    public MenuOperate getMenuOperateByCode(String menuId, String code) {
        QueryWrapper<MenuOperate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("menu_id", menuId);
        queryWrapper.eq("code", code);
        return menuOperateMapper.selectOne(queryWrapper);
    }

    @Override
    public void deleteMenuOperateByMenuId(String menuId) {
        QueryWrapper<MenuOperate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("menu_id", menuId);
        menuOperateMapper.delete(queryWrapper);
    }

    @Override
    public void deleteMenuOperateById(String id) {
        menuOperateMapper.deleteById(id);
    }
}
